package BeatBox;

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SimpleChatClient {
	JFrame frame;//图形结构
		JPanel incomingPanel;
			JScrollPane qScroller;
				JTextArea incoming;//接收区域
		JPanel outgoingpPanel;
			JTextField outgoing;//发送区域
			JButton sendButton;//发送按钮
		JPanel IPaddresspPanel;
			JTextField IPaddress;//获取IP地址和端口
			JButton linkButton;//局域网连接按钮
	BufferedReader reader;
	PrintWriter writer;
	ObjectOutputStream oStream;
	ObjectInputStream ois;
	Socket sock1;
	Socket sock2;
	boolean[] checkboxState;

	public static void main(String[] args) {
		SimpleChatClient client = new SimpleChatClient();
		client.go();
	}	

	public void go() {
		buildGui();		
		frame = new JFrame("Ludicrously Simple Chat Client");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(BorderLayout.NORTH,incomingPanel);
		frame.getContentPane().add(BorderLayout.CENTER,outgoingpPanel);
		frame.getContentPane().add(BorderLayout.SOUTH,IPaddresspPanel);
		frame.setBounds(499,271,538,400);
		frame.setVisible(true);
		IPaddress.selectAll();
		IPaddress.requestFocus();
		
	}
	
	public void buildGui()
	{
		incomingPanel = new JPanel();
		incoming = new JTextArea(15,50);
		qScroller = new JScrollPane(incoming);
		incoming.setLineWrap(true);//设置文本区的换行策略。如果设置为 true，则当行的长度大于所分配的宽度时，将换行。
		incoming.setWrapStyleWord(true);
		//设置换行方式（如果文本区要换行）。如果设置为 true，则当行的长度大于所分配的宽度时，将在单词边界（空白）处换行。
		incoming.setEditable(false);//设置指定的 boolean 变量，以指示此 TextComponent 是否应该为可编辑的。
		qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);//确定垂直滚动条何时显示在滚动窗格上。
		qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);//确定水平滚动条何时显示在滚动窗格上。
		incomingPanel.add(qScroller);

		outgoingpPanel = new JPanel();
		outgoing = new JTextField(20);
		sendButton = new JButton("Send");
		sendButton.addActionListener(new SendButtonListener());
		outgoingpPanel.add(outgoing);
		outgoingpPanel.add(sendButton);

		IPaddresspPanel = new JPanel();
		IPaddress = new JTextField(20);
		IPaddress.setText("192.168.8.246:4242");
		linkButton = new JButton("Link");
		linkButton.addActionListener(new LinkButtonListener());
		IPaddresspPanel.add(IPaddress);
		IPaddresspPanel.add(linkButton);
		
		outgoing.addKeyListener(new EnterListener());//添加监视器，实现按下回车后发送消息
	}
	
	public void setUpNetworking()//进行局域网连接 
	{
		try {
			String[] address =IPaddress.getText().split(":");
			String ip=address[0];
			int port=Integer.parseInt(address[1]);
			sock1 = new Socket(ip,port);
			sock2 = new Socket(ip,port+1);
			incoming.append("连接成功\n");

			InputStreamReader streamReader = new InputStreamReader(sock1.getInputStream());
			reader = new BufferedReader(streamReader);
			writer = new PrintWriter(sock1.getOutputStream());
			
			oStream= new ObjectOutputStream(sock2.getOutputStream());
			ois= new ObjectInputStream(new BufferedInputStream(sock2.getInputStream()));

			System.out.println("networking established");

			Thread readerThread1 = new Thread(new IncomingReader());
			readerThread1.start();

			Thread readerThread2 = new Thread(new RhythmReader());
			readerThread2.start();

			outgoing.requestFocus();
		}catch(IOException ex) {
			incoming.append("连接失败\n");
			ex.printStackTrace();
		}

	}

	public void sendText()//发送消息
	{
		if(!outgoing.getText().equals(""))
		{
			try {
				writer.println(outgoing.getText());
				writer.flush();//刷新该流的缓冲。 
				outgoing.setText("");
			}catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		outgoing.requestFocus();
		
	}
	
	public void sendRhythm(boolean[] checkboxState)
	{
		try {
            oStream.writeObject(checkboxState);
			// oStream.writeObject(null);
			// oStream.flush();
		}catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public class SendButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent ev) {
			sendText();
		}
	}

	public class LinkButtonListener implements ActionListener 
	{
		public void actionPerformed(ActionEvent ev) 
		{
			setUpNetworking();
		}
	}
	
	public class EnterListener implements KeyListener
	{

		@Override
		public void keyTyped(KeyEvent e) {
			// TODO Auto-generated method stub
		}

		@Override
		public void keyPressed(KeyEvent e) {
			if( KeyEvent.getKeyText(e.getKeyCode()).equals("Enter") ) 
			{
				sendText();
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {
			// TODO Auto-generated method stub
		}
	}
	public class IncomingReader implements Runnable {
		
		public void run() {
			String message;
			try {
				while((message = reader.readLine()) != null) {
					System.out.println("read "+ message);
					incoming.append(message + "\n");
					incoming.selectAll();
				}
			}catch (Exception ex) {
				incoming.append("连接已断开\n");
				ex.printStackTrace();
			}
		}
	}

	public class RhythmReader implements Runnable {
		public void run() {
			try {
				while((checkboxState = (boolean[])ois.readObject()) != null);
			}catch (Exception ex) {
				incoming.append("连接已断开\n");
				ex.printStackTrace();
			}
		}
	}
}





